<?php
namespace core\models;
/**
 * 字符串处理扩展函数类
 * @package    扩展库
 * @subpackage 字符串处理
 * @author     Howard
 */
class Strings {
    /**
     * 将字符串（中英文均可）切换成数组
     * @param string $str                 源字符串
     * @param string $charset          源字符串的编码，如gb2312,utf-8等
     * @param bool   $split_english_words 是否拆分英文单词，默认为拆分
     * @see    mb_str_split()
     * @return array 返回的数组，编码格式与$charset相同
     * @author ZhouHaoHua <53027327@qq.com>
     */
    public static function stringToArray( $str, $charset = 'utf-8', $split_english_words = true ) {
        $charset = strtolower($charset);
        if($charset!='utf-8'){
            $utf8_str = iconv( $charset, 'utf-8' . '//IGNORE', $str );
        }else{
            $utf8_str = $str;
        }

        if( $split_english_words === true ) {
            if(function_exists('mb_str_split')){
                $array = mb_str_split($utf8_str, 1, $charset);
            }else{
                $array = preg_split( '/(?<!^)(?!$)/u', $utf8_str );
            }

        } else {
            $array = preg_split( '/[\s,]+/u', $utf8_str );
            //$array = preg_split('/ /', $utf8_str, -1, PREG_SPLIT_OFFSET_CAPTURE);
            //$array = preg_split('//', $utf8_str, -1, PREG_SPLIT_NO_EMPTY);
        }

        if($charset!='utf-8') {
            $array = \Z::Arrays()->iconv( 'utf-8', $charset, $array );
        }
        return $array;
    }

    /**
     * 转换字符串至 NCR 如:汉字 -> &#27721;&#23383;
     * mb_convert_encoding($a, 'HTML-ENTITIES', 'gb2312')
     * @param string $str    源字符串
     * @param string $encode 源字符串的编码
     * @return string
     */
    public function stringToHtmlEntitiles( $str, $encode = "gb2312" ) {
        $output = mb_convert_encoding( $str, 'HTML-ENTITIES', $encode );
        return $output;
    }

    /**
     * 字符串转ASCII数字串
     * @param string $str       任意字符串
     * @param string $separator 生成数字串后的分隔符
     * @return bool|string
     */
    public function stringToAscii( $str, $separator = " " ) {
        if( $str == "" ) return false;
        $array = array();
        for( $i = 0; $i < strlen( $str ); $i++ ) {
            $CurrentStr = $str[ $i ];
            if( ord( $str[ $i ] ) > 127 ) {
                $CurrentStr = $str[ $i ] . $str[ ++$i ];
            }
            $a = ( unpack( "C*", $CurrentStr ) );
            $array[] = implode( '', $a );
        }
        return implode( $separator, $array );
    }

    /**
     * ASCII数字串转字符串
     * @param string $num_str   源数字串
     * @param string $separator 分割符
     * @return bool|string
     */
    public function asciiToString( $num_str, $separator = " " ) {
        if( !(int)$num_str ) return false;
        $array = explode( $separator, $num_str );
        $str = "";
        foreach( $array as $val ) {
            if( strlen( $val ) == 6 ) {
                $str .= chr( substr( $val, 0, 3 ) ) . chr( substr( $val, 3, 3 ) );
            } else {
                $str .= chr( $val );
            }
        }
        return $str;
    }

    /**
     * 全角数字转半角数字 Full-with to Half-width
     * @param string $Number
     * @return string
     */
    public function fw2hw( $Number ) {
        $array = array( "０", "１", "２", "３", "４", "５", "６", "７", "８", "９" );
        $array1 = array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" );
        $Number = str_replace( $array, $array1, $Number );
        return $Number;
    }

    /**
     * 半角数字转全角数字 Half-with to Full-width
     * @param string $Number
     * @return string
     */
    public function hw2fw( $Number ) {
        $array = array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" );
        $array1 = array( "０", "１", "２", "３", "４", "５", "６", "７", "８", "９" );
        $string = str_replace( $array, $array1, $Number );
        return $string;
    }

    /**
     * 将数位金额转换成中文大写数位
     * 例子: 231123.402 => 贰拾三万壹仟壹佰贰拾三元肆角整
     * @param float $num 表示金额的浮点数
     * @return string 返回中文大写的字串
     */
    public function trans2rmb( $num ) {
        $rtn = '';
        $num = round( $num, 2 );

        $s = array(); // 存储数位的分解部分
        //==> 转化为字串,$s[0]整数部分,$s[1]小数部分
        $s = explode( '.', strval( $num ) );

        // 超过12位(大於千亿)则不予处理
        if( strlen( $s[0] ) > 12 ) {
            return '*' . $num;
        }

        // 中文大写数位阵列
        $c_num = array( '零', '壹', '贰', '三', '肆', '伍', '陆', '柒', '捌', '玖' );

        // 保存处理过程资料的阵列
        $r = array();

        //==> 处理 分/角 部分
        if( !empty( $s[1] ) ) {
            $jiao = substr( $s[1], 0, 1 );
            if( !empty( $jiao ) ) {
                $r[0] .= $c_num[ $jiao ] . '角';
            } else {
                $r[0] .= '零';
            }

            $cent = substr( $s[1], 1, 1 );
            if( !empty( $cent ) ) {
                $r[0] .= $c_num[ $cent ] . '分';
            }
        }

        //==> 数字分为三截,四位一组,从右到左:元/万/亿,大於9位元的数字最高位元都归为"亿"
        $f1 = 1;
        for( $i = strlen( $s[0] ) - 1; $i >= 0; $i--, $f1++ ) {
            $f2 = floor( ( $f1 - 1 ) / 4 ) + 1; // 第几截
            if( $f2 > 3 ) {
                $f2 = 3;
            }

            // 当前数字
            $curr = substr( $s[0], $i, 1 );

            switch( $f1 % 4 ) {
                case 1:
                    $r[ $f2 ] = ( empty( $curr ) ? '零' : $c_num[ $curr ] ) . $r[ $f2 ];
                    break;
                case 2:
                    $r[ $f2 ] = ( empty( $curr ) ? '零' : $c_num[ $curr ] . '拾' ) . $r[ $f2 ];
                    break;
                case 3:
                    $r[ $f2 ] = ( empty( $curr ) ? '零' : $c_num[ $curr ] . '佰' ) . $r[ $f2 ];
                    break;
                case 0:
                    $r[ $f2 ] = ( empty( $curr ) ? '零' : $c_num[ $curr ] . '仟' ) . $r[ $f2 ];
                    break;
            }
        }

        $rtn .= empty( $r[3] ) ? '' : $r[3] . '亿';
        $rtn .= empty( $r[2] ) ? '' : $r[2] . '万';
        $rtn .= empty( $r[1] ) ? '' : $r[1] . '元';
        $rtn .= $r[0];

        if( empty( $s[1] ) ) //==>如果角和分部分都没有就以整为结尾
        {
            $rtn .= '整';
        }
        //==> 规则:如果位数为零,在"元"之前不出现"零",在空位处且不在"元"之间的,则填充一个"零"(num为0的情况除外)
        if( $num != 0 ) {
            while( 1 ) {
                if( substr_count( $rtn, "零零" ) == 0 && substr_count( $rtn, "零元" ) == 0
                    && substr_count( $rtn, "零万" ) == 0 && substr_count( $rtn, "零亿" ) == 0
                ) {
                    break;
                }
                $rtn = str_replace( "零零", "零", $rtn );
                $rtn = str_replace( "零元", "元", $rtn );
                $rtn = str_replace( "零万", "万", $rtn );
                $rtn = str_replace( "零亿", "亿", $rtn );
            }
        }
        return $rtn;
    }

    /**
     * 使用多个分隔符分割字符串成数组
     * @param string $separator 分隔符，如：,*.!
     * @param string $string    要被转的字符串
     * @return array
     */
    public function explodeMultiSeparator( $separator, $string ) {
        $array = array();
        $tok = strtok( $string, $separator );
        while( $tok !== false ) {
            $array[] = $tok;
            $tok = strtok( $separator );
        }
        return $array;
    }

    /**
     * 限制显示文字
     * @param string $cutstring 源字符串
     * @param int    $cutno     要显示的字数
     * @param string $endstr    尾巴符号
     * @return string 返回被剪切后的字符串
     */
    public function cutword( $cutstring, $cutno, $endstr = "..." ) {
        if( strlen( $cutstring ) > $cutno ) {
            for( $i = 0; $i < $cutno; $i++ ) {
                $ch = substr( $cutstring, $i, 1 );
                if( ord( $ch ) > 127 ) $i++;
            }
            $cutstring = substr( $cutstring, 0, $i ) . $endstr;
        }
        return $cutstring;
    }

    /**
     * 将汉字字符串分隔成数组
     * @param string $utf8String 源字符串（支持utf-8格式的汉字和其它文字）
     * @return array
     */
    public function split( $utf8String ) {
        return mb_str_split( $utf8String );
    }

    /**
     * 字符串安全转码【给输出模板前用】
     * @param string $str     要转码的字符串
     * @param string $charset 源编码，默认utf-8
     * @return string
     */
    public static function SafeOut( $str, $charset = 'utf-8' ) {
        if( is_numeric( $charset ) ) {
            $charset = 'utf-8';
        }
        return \Z::Arrays()->htmlspecialchars( $str, ENT_QUOTES | ENT_HTML5, $charset );
    }

    /**
     * 把中文的逗号之类的给替换成英文的
     * @param string $str
     * @author tieGump
     * @return string
     */
    public function clearComma( $str ) {
        $str = str_replace( '，', ',', $str );
        $str = str_replace( '。', ',', $str );
        $str = str_replace( '.', ',', $str );
        $str = str_replace( ',,', ',', $str );
        return $str;
    }

    /**
     * 对单引号和双引号进行反转义
     * @param string $string
     * @return string
     */
    public static function stripslashes2( $string ) {
        $string = str_replace( "\\\"", "\"", $string );
        $string = str_replace( "\\'", "'", $string );
        if( stripos( $string, "\\\\" ) !== false ) {
            $string = str_replace( "\\\\", "\\", $string );
        }
        return $string;
    }

    /**
     * 判断为空
     * @param $value
     * @return bool
     * @author lwkai
     * @date   2016-1-18
     */
    public static function notNull( $value ) {
        if( is_array( $value ) ) {
            if( sizeof( $value ) > 0 ) {
                return true;
            } else {
                return false;
            }
        } else {
            if( ( $value != '' ) && ( strtolower( $value ) != 'null' ) && ( strlen( trim( $value ) ) > 0 ) ) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 生成UUID值
     * @param string $prefix 可以指定前缀，也可以不指定
     * @param string $sp     分隔符，默认为-
     * @return string 返回生成的uuid值
     * @author ZhouHaoHua <53027327@qq.com>
     */
    public static function uuidCreate( $prefix = "", $sp = "-" ) {    //可以指定前缀
        $str = md5( uniqid( mt_rand(), true ) );
        $uuid = substr( $str, 0, 8 ) . $sp;
        $uuid .= substr( $str, 8, 4 ) . $sp;
        $uuid .= substr( $str, 12, 4 ) . $sp;
        $uuid .= substr( $str, 16, 4 ) . $sp;
        $uuid .= substr( $str, 20, 12 );
        return $prefix . $uuid;
    }

    /**
     * 判断字符串是否为Json格式
     * @param string     $data  源字符串
     * @return array|bool|object 成功返回转换后的对象或数组，失败返回 false
     * @author ZhouHaoHua <53027327@qq.com>
     */
    public static function isJson( string $data) {
        json_decode( $data);
        return json_last_error() === JSON_ERROR_NONE;
    }

    /**
     * 字符串转Unicode编码
     * @param $strLong
     * @return string
     * @author ZhouHaoHua <53027327@qq.com>
     * @date   date
     */
    public function unicode_encode( $strLong ) {
        $strArr = preg_split( '/(?<!^)(?!$)/u', $strLong );//拆分字符串为数组(含中文字符)
        $resUnicode = '';
        foreach( $strArr as $str ) {
            $bin_str = '';
            $arr = is_array( $str ) ? $str : str_split( $str );//获取字符内部数组表示,此时$arr应类似array(228, 189, 160)
            foreach( $arr as $value ) {
                $bin_str .= decbin( ord( $value ) );//转成数字再转成二进制字符串,$bin_str应类似111001001011110110100000,如果是汉字"你"
            }
            $bin_str = preg_replace( '/^.{4}(.{4}).{2}(.{6}).{2}(.{6})$/', '$1$2$3', $bin_str );//正则截取, $bin_str应类似0100111101100000,如果是汉字"你"
            $unicode = dechex( bindec( $bin_str ) );//返回unicode十六进制
            $_sup = '';
            for( $i = 0; $i < 4 - strlen( $unicode ); $i++ ) {
                $_sup .= '0';//补位高字节 0
            }
            $str = '\\u' . $_sup . $unicode; //加上 \u  返回
            $resUnicode .= $str;
        }
        return $resUnicode;
    }

    /**
     * Unicode编码转字符串方法
     * @param $name
     * @return string
     * @author ZhouHaoHua <53027327@qq.com>
     * @date   date
     */
    public function unicode_decode( $name ) {
        // 转换编码，将Unicode编码转换成可以浏览的utf-8编码
        $pattern = '/([\w]+)|(\\\u([\w]{4}))/i';
        preg_match_all( $pattern, $name, $matches );
        if( !empty( $matches ) ) {
            $name = '';
            for( $j = 0; $j < count( $matches[0] ); $j++ ) {
                $str = $matches[0][ $j ];
                if( strpos( $str, '\\u' ) === 0 ) {
                    $code = base_convert( substr( $str, 2, 2 ), 16, 10 );
                    $code2 = base_convert( substr( $str, 4 ), 16, 10 );
                    $c = chr( $code ) . chr( $code2 );
                    $c = iconv( 'UCS-2', 'UTF-8', $c );
                    $name .= $c;
                } else {
                    $name .= $str;
                }
            }
        }
        return $name;
    }

    /**
     * Unicode编码转字符串2
     * @param $str utf-8字符串
     * @return string
     * @author ZhouHaoHua <53027327@qq.com>
     * @date   date
     */
    public function unicode_decode2( $str ) {
        $json = '{"str":"' . $str . '"}';
        $arr = json_decode( $json, true );
        if( empty( $arr ) ) return '';
        return $arr['str'];
    }

}